home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / GMSMTH01.ZIP / SPRDEMO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-08  |  17.0 KB  |  561 lines

  1. /*
  2.  
  3.     sprdemo.c
  4.  
  5.     Internet: alexad3@icebox.iceonline.com
  6.     Copyright 1995, April 13 by Bruce Miller, ALL rights reserved
  7.  
  8.  
  9.     Created - 1995/4/13
  10.  
  11.     History:
  12.         New file
  13.  
  14.  
  15.     Modified 28April95 by Bruce Miller:
  16.  
  17.        * Added on-screen instructions
  18.  
  19.        * Added user control of goodguy's arm position.
  20.  
  21.        * Changed sprite draw routines to call move_limit_all_banks()
  22.          and draw_all_banks() since sprBank.C now takes care of
  23.          list of sprite banks.
  24.  
  25.        NOTE: Main files (like this one) need only define pointers to
  26.              each sprite bank.
  27.  
  28.  
  29.  
  30. */
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <conio.h>
  35. #include <time.h>
  36.  
  37. #include <g_io.h>
  38. #include <die.h>
  39. #include <gmalloc.h>
  40. #include <pr2.h>
  41. #include <g_def.h>
  42. #include <gui.h>
  43. #include <gtimer.h>
  44. #include <erase.h>
  45. #include <colors.h>
  46.  
  47. #include <xlib_all.h>
  48.  
  49. #include <sprite.h>
  50. #include <sprbank.h>
  51.  
  52. //------- Constants ---------
  53. #define ENABLE_ERASE 1
  54. #define NO_ERASE 0
  55.  
  56. #define NUM_GOODGUY_SPRITES 1
  57. #define NUM_BADGUY_SPRITES 3
  58. #define NUM_EXPLOSION_SPRITES 5
  59. #define NUM_BALL_SPRITES 3
  60. #define NUM_MISSILE_SPRITES 8
  61.  
  62.  
  63. // clipping rectangle
  64. #define clip_left 40
  65. #define clip_right 312
  66. #define clip_top 10
  67. #define clip_bott 168
  68.  
  69. enum SpriteBankIDs {GGUY_ID,RBOOTJET_ID, LBOOTJET_ID, BADGUY_ID, EXPLD_ID,
  70.                     BALL_ID, MISSILE_ID};
  71.  
  72. //--------- Local storage ----------
  73. static int  gameOver = 0;
  74. static USHORT badGuysStarted=0, badGuysHit=0;
  75.  
  76. sprite_bank_t far *ballBank, far *badGuyBank, far *explodeBank,
  77.               far *missileBank, far *gguyBank,
  78.               far *rBootJetBank, far *lBootJetBank;
  79.  
  80. static sprite_t far *gguy, far *ball, far *rBootJet, far *lBootJet;
  81. static short paused = 0;
  82. static short gguyArmPos=1;
  83. static short eboltYVel[] = {2,0,-2}; // based on arm position(down,center,up)
  84.  
  85.  
  86. /*--- Local Function Prototypes ---*/
  87. static void userControl( void);
  88. static void startNewBadGuy( void );
  89. static void animate(void);
  90. static void updateScreenInfo( void);
  91. static void drawScreen(void);
  92. static void intro( void );
  93.  
  94. /*---------------------------------------------------------------------------
  95.  
  96.     main()
  97.  
  98. ---------------------------------------------------------------------------*/
  99. void main( void )
  100. {
  101. char gamePalette[768];
  102.  
  103.    randomize();
  104.  
  105. #if 0
  106.    clrscr();
  107.    printf("\n\n\n SPRITE LIBRARY DEMO                          (c) Copyright Bruce Miller 1995\n");
  108.    printf("\n\n <Arrow keys, Joystick = Move Goodguy>  <SpaceBar = Shoot Robots>    \n");
  109.    printf("\n <Mouse just moves cursor arrow>    \n");
  110.    printf("\n\n <P = Pause/SingleStep, Enter = Resume>  <Escape = Exit>   \n");
  111.  
  112.    printf("\n\n\n\tPress a key to start...  \n");
  113.    getch();
  114. #endif
  115.  
  116.    clear_pr2();
  117.    pr2("at the top");
  118.  
  119.  
  120.    init_exit();
  121.  
  122.    init_mem_list();
  123.  
  124.    init_timer();
  125.  
  126.    init_xmode_video();
  127.  
  128.    gb_auto_repeat=0;
  129.    want_mouse_moves=0;
  130.    init_events("crshair.cbm");
  131.  
  132.  
  133.    load_palette( "bruce.pal", gamePalette);
  134.    setvgapalette(gamePalette);
  135.  
  136.    drawScreen();
  137.  
  138.    /* set aside mem etc.. for 64 erase rects, not to exceed 32k */
  139.    init_gb_erase(64, 32767);
  140.    page = 0;
  141.  
  142.    // Read sprites from files, intialize...
  143.    // NOTE: init order determines which sprites drawn over top of others
  144.    //  ie: first initialized will be first drawn, therefore last initialized
  145.    //  will be drawn over top of others
  146.    init_sprites();
  147.    ballBank= setup_spritebank("stlball.spr", NUM_BALL_SPRITES, BALL_ID,
  148.                            0, ScrnPhysicalPixelWidth, 0, ScrnPhysicalHeight,
  149.                            0, ScrnPhysicalPixelWidth, 0, ScrnPhysicalHeight,
  150.                             ENABLE_ERASE, NUM_BALL_SPRITES);
  151.  
  152.    badGuyBank= setup_spritebank("robot.spr", NUM_BADGUY_SPRITES, BADGUY_ID,
  153.                            clip_left, clip_right, clip_top, clip_bott,
  154.                            clip_left, clip_right, clip_top, clip_bott,
  155.                            ENABLE_ERASE, NUM_BADGUY_SPRITES);
  156.  
  157.    explodeBank= setup_spritebank("explode1.spr", NUM_EXPLOSION_SPRITES,EXPLD_ID,
  158.                            clip_left, clip_right, clip_top, clip_bott,
  159.                            clip_left, clip_right, clip_top, clip_bott,
  160.                            ENABLE_ERASE, NUM_EXPLOSION_SPRITES);
  161.  
  162.    gguyBank= setup_spritebank("batsuit.spr",   NUM_GOODGUY_SPRITES, GGUY_ID,
  163.                            clip_left, clip_right, clip_top, clip_bott,
  164.                            clip_left, clip_right, clip_top, clip_bott,
  165.                            ENABLE_ERASE, NUM_GOODGUY_SPRITES);
  166.  
  167.    rBootJetBank= setup_spritebank("rBootJet.spr",   NUM_GOODGUY_SPRITES, RBOOTJET_ID,
  168.                            clip_left, clip_right, clip_top, clip_bott,
  169.                            clip_left, clip_right, clip_top, clip_bott,
  170.                            ENABLE_ERASE, NUM_GOODGUY_SPRITES);
  171.  
  172.    lBootJetBank= setup_spritebank("lBootJet.spr",   NUM_GOODGUY_SPRITES, LBOOTJET_ID,
  173.                            clip_left, clip_right, clip_top, clip_bott,
  174.                            clip_left, clip_right, clip_top, clip_bott,
  175.                            ENABLE_ERASE, NUM_GOODGUY_SPRITES);
  176.  
  177.    missileBank= setup_spritebank("eball.spr", NUM_MISSILE_SPRITES, MISSILE_ID,
  178.                            clip_left, clip_right, clip_top, clip_bott,
  179.                            clip_left, clip_right, clip_top, clip_bott,
  180.                            ENABLE_ERASE, NUM_MISSILE_SPRITES);
  181.  
  182.    // start good guy sprite, ball sprite
  183.    // initialize the pointers to the special sprites
  184.    gguy = gguyBank->sprites;
  185.    rBootJet = rBootJetBank->sprites;
  186.    lBootJet = lBootJetBank->sprites;
  187.  
  188.    start_sprite(gguy, SPR_CHG_STOP, SPR_HOLD_AT_XYLIMIT, clip_left+20, clip_top+20, 0,1);
  189.    start_sprite(rBootJet, SPR_CHG_FORWARD, SPR_HOLD_AT_XYLIMIT, clip_left+20, clip_top+20, 1,1);
  190.    start_sprite(lBootJet, SPR_CHG_FORWARD, SPR_HOLD_AT_XYLIMIT, clip_left+20, clip_top+20, 1,1);
  191.    set_bitmap( gguy, gguyArmPos );
  192.  
  193.    ball = ballBank->sprites;
  194.    start_sprite(ball, -1, SPR_BOUNCE_AT_XYLIMIT, clip_left+20, clip_top, 1, 1);
  195.    ball = ballBank->sprites+1;
  196.    start_sprite( ball, -1, SPR_BOUNCE_AT_XYLIMIT, clip_left+10, clip_top+50,
  197.                -1, -1 );
  198.  
  199.    // start 3rd ball, set clip/limit rectangle differently from other 2
  200.    ball = ballBank->sprites+2;
  201.    ball->x_min = clip_left; ball->x_max = clip_right;
  202.    ball->y_min = clip_top; ball->y_max = clip_bott;
  203.    start_sprite(ball, -1, SPR_BOUNCE_AT_XYLIMIT, clip_left+100, clip_top, 1,-1);
  204.  
  205.    // draw screen, flip pages, draw on other page too
  206.    page = 0;
  207.  
  208.    intro();
  209.  
  210.    while(!gameOver)
  211.       {
  212.       startNewBadGuy();  // starts a new bad guy whenever one goes inactive
  213.       userControl();
  214.       animate();
  215.       updateScreenInfo();
  216.       gui_draw_mouse();
  217.       x_page_flip(PhysScrnXOffs,PhysScrnYOffs);
  218.       page= page ? 0 : 1;
  219.       }
  220.  
  221.    // terminate in the opposite order to the initialize
  222.    deinit_sprites();
  223.    deinit_gb_erase();
  224.    deinit_events();
  225.    deinit_xmode_video();
  226.    deinit_timer();
  227. }
  228.  
  229. #define SCROLL_PIXELS 4
  230. /*---------------------------------------------------------------------------
  231.  
  232.     animate()
  233.  
  234. ---------------------------------------------------------------------------*/
  235. static void animate(void)
  236. {
  237. sprite_t far *sPtr;
  238.  
  239.    /* erase old stuff */
  240.    draw_erase_rects(&(gb_h[page]));
  241.  
  242.    move_limit_all_banks();
  243.  
  244.    // locate the boot jet sprites with respect to the goodguy sprite
  245.    // according to the multi-purpose x and y offsets set using sprutil.exe
  246.    rBootJet->x = gguy->x+gguy->x_offs2-rBootJet->prev_cx;
  247.    rBootJet->y = gguy->y+gguy->y_offs2-rBootJet->prev_cy;
  248.    lBootJet->x = gguy->x+gguy->x_offs3-lBootJet->prev_cx;
  249.    lBootJet->y = gguy->y+gguy->y_offs3-lBootJet->prev_cy;
  250.  
  251.    draw_all_banks();
  252.  
  253.    //--- check for missiles hitting bad guys
  254.    if( (sPtr = detect_collisions(0, missileBank, badGuyBank) ) != NULL )
  255.     {
  256.     sPtr->change_mode = SPR_CHG_DEAD;
  257.     start_next_in_spritebank(explodeBank,   SPR_CHG_FORW_DIE,
  258.                                SPR_NO_LIMITS, sPtr->x+(sPtr->curr_width>>2),
  259.                                sPtr->y+(sPtr->curr_height>>2), 0, 0);
  260.     badGuysHit++;
  261.     }
  262. }
  263.  
  264. /*---------------------------------------------------------------------------
  265.  
  266.     userControl()
  267.  
  268. ---------------------------------------------------------------------------*/
  269. static void userControl( void)
  270. {
  271. event_t event;
  272. short gotEvent = 0;
  273.  
  274.       if ( paused )
  275.     while( !gotEvent )
  276.        gotEvent = get_event(&event);
  277.       else
  278.     gotEvent = get_event(&event);
  279.  
  280.       if ( gotEvent )
  281.      {
  282.     switch ( event.type )
  283.             {
  284.             case E_JOY_X_LEFT:
  285.                gguy->dx=-1;
  286.                break;
  287.  
  288.             case E_JOY_X_CENTRE:
  289.                gguy->dx=0;
  290.                break;
  291.  
  292.             case E_JOY_X_RIGHT:
  293.                gguy->dx=1;
  294.                break;
  295.  
  296.             case E_JOY_Y_UP:
  297.                gguy->dy=-1;
  298.                break;
  299.  
  300.             case E_JOY_Y_CENTRE:
  301.                gguy->dy=0;
  302.                break;
  303.  
  304.             case E_JOY_Y_DOWN:
  305.                gguy->dy=1;
  306.                break;
  307.  
  308.             case E_B0_DN:
  309.             case E_B1_DN:
  310.             //--- launch bolt ---
  311.             start_next_in_spritebank( missileBank, SPR_CHG_FORW_HOLD,
  312.                      SPR_DIE_AT_XYLIMIT, gguy->x+gguy->x_offs1,
  313.                    gguy->y+gguy->y_offs1, 7, eboltYVel[gguy->icurr_bitmap] );
  314.                break;
  315.  
  316.        case E_KEY:
  317.           if ( event.sub_type == E_DOWN )
  318.         {
  319.         switch( event.d2 )
  320.            {
  321.            case ESC:
  322.               gameOver = 1;
  323.               break;
  324.  
  325.                      case (KM_CTRL_PLUS|UP):
  326.                        gguyArmPos++;
  327.                        if( gguyArmPos > 2)
  328.                          gguyArmPos = 2;
  329.                        set_bitmap( gguy, gguyArmPos );
  330.                        break;
  331.                      case (KM_CTRL_PLUS|DOWN):
  332.                        gguyArmPos--;
  333.                        if( gguyArmPos < 0 )
  334.                          gguyArmPos = 0;
  335.                        set_bitmap( gguy, gguyArmPos );
  336.                        break;
  337.  
  338.            case UP:     gguy->dy=-1;  break;
  339.            case DOWN:   gguy->dy=1;  break;
  340.            case LEFT:   gguy->dx=-1;  break;
  341.            case RIGHT:  gguy->dx=1;  break;
  342.            case HOME:   gguy->dx = gguy->dy = 0;  break;
  343.            case SPACE:
  344.               //--- launch bolt ---
  345.                         start_next_in_spritebank( missileBank,
  346.                                   SPR_CHG_FORW_HOLD,   SPR_DIE_AT_XYLIMIT,
  347.                                   gguy->x+gguy->x_offs1, gguy->y+gguy->y_offs1,
  348.                                   7, eboltYVel[gguy->icurr_bitmap] );
  349.                         break;
  350.  
  351.            case 'p':
  352.            case 'P':
  353.              paused = 1;
  354.              break;
  355.  
  356.            case CR:
  357.               paused = 0;
  358.               break;
  359.            }
  360.           }
  361.              else
  362.                {
  363.            if ( event.sub_type == E_UP )
  364.                   {
  365.                   switch ( event.d2 )
  366.                      {
  367.            case UP:     gguy->dy=0;  break;
  368.            case DOWN:   gguy->dy=0;  break;
  369.            case LEFT:   gguy->dx=0;  break;
  370.            case RIGHT:  gguy->dx=0;  break;
  371.                      }
  372.                   }
  373.                }
  374.           break;
  375.             }
  376.  
  377.     }
  378. }
  379.  
  380. #define INTRO_TIME 200
  381. #define ARM_MOVE_TIME 6
  382.  
  383. /*---------------------------------------------------------------------------
  384.  
  385.    intro()
  386.  
  387. ---------------------------------------------------------------------------*/
  388. static void intro( void )
  389. {
  390. static long introTime, armMoveTime;
  391. static short armDirUp=1;
  392.  
  393.    introTime = fast_tick + INTRO_TIME;
  394.    armMoveTime = fast_tick + ARM_MOVE_TIME;
  395.    while( fast_tick < introTime )
  396.       {
  397.  
  398.       // move ggguy up and down
  399.       if ( gguy->y > 110 && gguy->dy > -1 )
  400.          gguy->dy= -1;
  401.       else
  402.          if ( gguy->y < 20 && gguy->dy < 1 )
  403.             gguy->dy= 1;
  404.  
  405.       // move good guy's arm, shoot
  406.       if ( fast_tick > armMoveTime )
  407.          {
  408.          // move arm up and down
  409.          if ( armDirUp )
  410.             {
  411.             gguyArmPos++;
  412.             if ( gguyArmPos > 2)
  413.                {
  414.                gguyArmPos = 2;
  415.                armDirUp=0;
  416.                }
  417.             }
  418.          else
  419.             {
  420.             gguyArmPos--;
  421.             if( gguyArmPos < 0 )
  422.               {
  423.               gguyArmPos = 0;
  424.               armDirUp=1;
  425.               }
  426.             }
  427.          set_bitmap( gguy, gguyArmPos );
  428.  
  429.          // shoot
  430.          start_next_in_spritebank( missileBank,
  431.                                 SPR_CHG_FORW_HOLD, SPR_DIE_AT_XYLIMIT,
  432.                                 gguy->x+gguy->x_offs1, gguy->y+gguy->y_offs1,
  433.                                 7, eboltYVel[gguy->icurr_bitmap] );
  434.  
  435.          armMoveTime = fast_tick + ARM_MOVE_TIME;
  436.          }
  437.       startNewBadGuy();  // starts a new bad guy whenever one goes inactive
  438.       userControl();
  439.       animate();
  440.       updateScreenInfo();
  441.       gui_draw_mouse();
  442.       x_page_flip(PhysScrnXOffs,PhysScrnYOffs);
  443.       page= page ? 0 : 1;
  444.       }
  445.  
  446.      // set goodguy's arm position to middle
  447.      gguyArmPos=1;
  448.      set_bitmap( gguy, gguyArmPos );
  449.  
  450. }
  451.  
  452. /*---------------------------------------------------------------------------
  453.  
  454. startNewBadGuy()
  455.  
  456. ---------------------------------------------------------------------------*/
  457. static void startNewBadGuy( void )
  458. {
  459. int i;
  460. sprite_t far *sPtr;
  461.  
  462.    for(i = 0; i < NUM_BADGUY_SPRITES; i++)
  463.       {
  464.       sPtr = badGuyBank->sprites+i;
  465.       if( sPtr->change_mode == SPR_CHG_DEAD )
  466.          {
  467.          start_scaled_sprite( sPtr, SPR_CHG_FORWARD, SPR_CLIP_DIE_AT_XYLIMIT,
  468.             clip_right-4, (rand()%100)+clip_top+20, -((rand() % 2)+1), ((rand() % 3)-1),
  469.             10, 15, PROPORTIONAL, 1 );    //initial scale factor, dw, dh
  470.          sPtr->h_max = 40;  // maximum height of scaled sprite
  471.          badGuysStarted++;
  472.          break;
  473.          }
  474.       }
  475. }
  476.  
  477. #define TICKS_PER_SECOND 60
  478.  
  479. /*---------------------------------------------------------------------------
  480.  
  481.     updateScreenInfo()
  482.  
  483. ---------------------------------------------------------------------------*/
  484. static void updateScreenInfo( void)
  485. {
  486. static short frameCount, framesPerSecond;
  487. static long frameTimer;
  488.  
  489.    frameCount++;
  490.    if ( fast_tick < frameTimer )
  491.       return;
  492.  
  493.    frameTimer = fast_tick + TICKS_PER_SECOND;
  494.    framesPerSecond = frameCount;
  495.    frameCount = 0;
  496.  
  497.    x_bgprintf(6,205,VisiblePageOffs,EGA_YELLOW,EGA_BLACK,
  498.      (char far *)"Frames/sec:%2d Robots hit:%d Hit/Escaped:%d\%",
  499.      framesPerSecond, badGuysHit, (short)((long)(badGuysHit*100)/badGuysStarted) );
  500.  
  501.    x_bgprintf(6,205,HiddenPageOffs,EGA_YELLOW,EGA_BLACK,
  502.      (char far *)"Frames/sec:%2d Robots hit:%d Hit/Escaped:%d\%",
  503.      framesPerSecond, badGuysHit, (short)((long)(badGuysHit*100)/badGuysStarted) );
  504.  
  505. }
  506.  
  507. /*---------------------------------------------------------------------------
  508.  
  509.    drawScreen()
  510.  
  511. ---------------------------------------------------------------------------*/
  512. static void drawScreen(void)
  513. {
  514. BYTE far *bck;
  515.  
  516.  
  517.    LeftClip= clip_left/4; RightClip= clip_right/4-1;
  518.    TopClip= clip_top;   BottomClip= clip_bott;
  519.  
  520.  
  521.    bck=(BYTE far *)far_load("bck.pbm");
  522.    if ( bck )
  523.       {
  524.       x_put_pbm_clipxy(40,10, HiddenPageOffs , bck);
  525.       x_put_pbm_clipxy(40,10, VisiblePageOffs, bck);
  526.       gfree(bck, "bck.pbm");
  527.       }
  528.  
  529.    // draw clipping rectangle
  530.    x_line(clip_left-1,clip_top-1,clip_right,clip_top-1,EGA_WHITE,VisiblePageOffs);
  531.    x_line(clip_right,clip_top-1,clip_right,clip_bott, EGA_WHITE,VisiblePageOffs);
  532.    x_line(clip_right,clip_bott,clip_left-1,clip_bott,EGA_WHITE,VisiblePageOffs);
  533.    x_line(clip_left-1,clip_bott,clip_left-1,clip_top-1,EGA_WHITE,VisiblePageOffs);
  534.  
  535.    x_line(clip_left-1,clip_top-1,clip_right,clip_top-1,EGA_WHITE,HiddenPageOffs);
  536.    x_line(clip_right,clip_top-1,clip_right,clip_bott, EGA_WHITE,HiddenPageOffs);
  537.    x_line(clip_right,clip_bott,clip_left-1,clip_bott,EGA_WHITE,HiddenPageOffs);
  538.    x_line(clip_left-1,clip_bott,clip_left-1,clip_top-1,EGA_WHITE,HiddenPageOffs);
  539.  
  540.    // print instructions
  541.    x_printf(7,221,VisiblePageOffs,EGA_DARKGRAY,
  542.     (char far *)"<ArrowKeys,Joystick=Move><SpaceBar=Shoot>");
  543.    x_printf(6,220,VisiblePageOffs,EGA_RED,
  544.     (char far *)"<ArrowKeys,Joystick=Move><SpaceBar=Shoot>");
  545.  
  546.    x_printf(7,231,VisiblePageOffs,EGA_DARKGRAY,
  547.     "<Ctrl+Up/Dn=Move Goodguy's arm up/down>");
  548.    x_printf(6,230,VisiblePageOffs,EGA_RED,
  549.     "<Ctrl+Up/Dn=Move Goodguy's arm up/down>");
  550.  
  551.    x_printf(7,221,HiddenPageOffs,EGA_DARKGRAY,
  552.     (char far *)"<ArrowKeys,Joystick=Move><SpaceBar=Shoot>");
  553.    x_printf(6,220,HiddenPageOffs,EGA_RED,
  554.     (char far *)"<ArrowKeys,Joystick=Move><SpaceBar=Shoot>");
  555.    x_printf(7,231,HiddenPageOffs,EGA_DARKGRAY,
  556.     "<Ctrl+Up/Dn=Move Goodguy's arm up/down>");
  557.    x_printf(6,230,HiddenPageOffs,EGA_RED,
  558.     "<Ctrl+Up/Dn=Move Goodguy's arm up/down>");
  559.  
  560. }
  561.